home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------*/
- /* TOOLPACK/1 Release: 1.1 */
- /*-------------------------------*/
- #include <ctype.h>
- #include "define.h"
-
- #include <sys/types.h>
- #include <sys/time.h>
- #ifdef sgi
- #include <time.h>
- #endif
-
- #ifdef sgi
- #define checkfd chckfd
- #define checkfn chckfn
- #endif
-
-
- #include <sys/stat.h>
-
- #include <sys/dir.h>
-
- #include "globals1.h"
- #include "globals2.h"
- #include "globals.h"
-
-
- crtzlng(charnam, access, fd)
- char *charnam;
- int access, fd;
- {
-
- /* the file charnam exists and may be open with associated file
- descriptor fd. crtzlng truncates this file to zero length
- and opens it in mode access */
-
- int uid,gid,len,i;
- char newch[MAXPATH];
- struct stat sbuf;
-
- int status;
-
- close(fd);
-
- /* truncate to zero length */
- status = creat(charnam, RWXMODE);
-
-
- /* now close and open again to get the access across */
- close(status);
-
- status = open(charnam, access);
-
- return(status);
- /* THIS CAN BE IMPROVED FOR 4.2 */
-
-
- }
-
- flush(fd)
- int fd;
- {
-
- /* flush the buffer associated with the file descriptor fd */
-
- struct fdinfo *ptr;
-
- /* no effect if no charcaters in the buffer or current
- access not write */
- ptr = &files[fd];
- if (ptr->chrleft == 0 || ptr->caccess != WRITE) return;
-
- /* write characters to file */
- write(fd, ptr->buffer, ptr->chrleft);
- return;
-
- }
-
-
- fndnblk(end, length)
- char *end;
- int length;
- {
-
- /* end points at the newline at the end of a string of length
- length (i.e. position length = NEWLINE). fndnblk finds the
- first non-space character preceding this NEWLINE. Inserts
- a newline after this character and returns the new string
- length via the function name */
-
- int i;
-
- for (i=length-1; i>=1; i--)
- if (*--end != BLANKCH && *end != TABCH) break;
-
- /* either i=0 & end is left at character position 1
- or i>0 and end is pointing at the last non-space character */
- if (i!=0) end++;
- *end = NEWLINE;
- return(++i);
-
- }
-
- isaname(name)
- char *name;
- {
-
- /* returns YES if name is a 'pure' name (no SLASHES)
- NO otherwise */
-
- while (*name != EOSCH && *name != SLASHCH) name++;
-
- return(*name == EOSCH ? YES :NO);
-
- }
-
- isafile(pathnam)
- char *pathnam;
- {
-
- /* returns YES if pathname exists NO otherwise */
-
- struct stat buf;
-
- return ((stat(pathnam, &buf) == -1) ? NO :YES );
-
- }
-
- isadir(pathnam)
- char *pathnam;
- {
-
- /* returns YES if pathname is a directory NO otherwise */
-
- struct stat buf;
-
- if (stat(pathnam, &buf) == -1) return(NO);
-
- return(((buf.st_mode & S_IFMT) == S_IFDIR) ? YES : NO);
-
- }
-
-
-
- /* this is from allio.c */
-
-
- checkfd(fd)
- int fd;
-
- {
- /* check file descriptor value
-
- return NOTINRANGE if fd does not belong to [0, MAXFILE]
-
- DEVICE if fd belongs to [0, DEVFD]
-
- FILES if fd belongs to [FIRSTFD, MAXFILE-1] */
-
-
- if( fd < 0 || fd > MAXFILE )
- return(NOTINRANGE);
-
- if( fd >= 0 && fd <= DEVFD)
- return(DEVICE);
-
- return(FILES);
-
- }
-
- checkfn(charnm1)
- char *charnm1;
-
- {
- /* check the character string charname forms a valid path
- name i.e the individual components making up the
- path name do not exceed MAXNAME-1 characters in length
- NOTE : MAXLINE includes the EOS character according to TRD */
- int len = 0;
- char ch;
-
- /* loop to end of string */
- while (( ch = *charnm1++) != EOSCH)
- {if (ch != SLASHCH) len++ ;
-
- /* ch is a SLASH check length of string */
- else
- { if (len >= MAXNAME) return(ERR) ;
-
- /* otherwise zero length for next component */
- else len = 0;
- }
- }
-
- /* check last component */
- return((len >= MAXNAME) ? ERR : NOERR);
-
- }
-
- chkrnum(recnum, fd)
- int recnum, fd;
- {
-
- /* check if the value of recnum, the record number in a direct
- access file is in range. The value of MAXREC, the maximum
- number of records allowed in a particular file, is stored
- as the first record of the file and its value is placed
- in files[fd].charsleft on creation or opening of the file */
-
- struct fdinfo *ptr;
- ptr = &files[fd];
- if (recnum > ptr->chrleft || recnum <= 0) return(ERR);
-
- return(NOERR);
- }
-
- /* routines for performing IST string to C string and vice versa */
- /*CENTRY*/
- istchr_(istname, charnm1)
- int *istname;
- char *charnm1;
- {
- char junk;
- /* convert an IST string to a C string */
- while( *istname != EOS)
- zcitoc_(charnm1++,1L,istname++,&junk);
- *charnm1 = EOSCH;
- }
-
- chist_(s,iststr,length)
- int *iststr;
- long int length;
- char *s;
- {
- /* makes an ist string out of an f77 character variable
- * stripping off trailing blanks */
-
- char *ptr;
- int junk;
- if(length){
- ptr = s + length - 1;
- while(ptr >= s && *ptr == BLANKCH)
- ptr--;
- for(;s <= ptr;*iststr++ = zcctoi_(s++,&junk));
- *iststr = EOS;
- }
- else *iststr = EOS;
- }
- /*ENDCENTRY*/
-
- nxtfld(ptr, field)
- char *ptr, *field;
- {
-
- /* get the next field out of the given filename and put it in
- field. Fields are separated by a slash and the string ends
- with an EOS. The search starts at ptr.
- nextfield returns OK if more fields are present or EOS if
- the final field has been extracted. */
-
- for(; *ptr != SLASHCH && *ptr != EOSCH; *field++ = *ptr++) ;
-
- /* move the pointer over the slash if it is present */
- if (*ptr == SLASHCH) ptr++;
-
-
- *field = EOSCH;
-
- return (*ptr == EOSCH ? EOS : OK );
-
- }
-
- mkpath(name, path)
- char *name, *path;
- {
-
- /* generate the pathname (path) from the current local directory
- (localdir - external) and the given name (name)
-
- ./ = current directory
- ../ = parent directory
- / as first character signifies a full path relative to root */
-
- char *ptr, *end, field[MAXPATH];
- int exit, flen;
-
- /* check that the path name is valid i.e. no fields
- exceed MAXPATH-1 characters in length */
- if (checkfn(name) == ERR) return(ERR);
- strcpy(path, root);
-
- /* complete pathname case */
- if (*name == SLASHCH) {
- strcat(path,name);
- return(OK);
- }
-
- /* path is given relative to local directory */
-
- /* copy non-null local directory path into path */
- if (strlen(lcldir) != 0){
- strcat(path, "/");
- strcat(path, lcldir);
- }
-
- ptr = name; /* point at start of name */
- end = path + strlen(path); /* point at EOS in path */
-
- /* split up name a field at a time */
- if (ptr == end) return(OK); /* exit on null names */
- do {
- exit = nxtfld(ptr, field);
-
- /* include the slash - before in path and after in name */
- flen = strlen(field) + 1;
-
-
- ptr += flen ; /* move ptr to start of next field */
-
- if (strcmp(field,"./") == 0 || strcmp(field,".") == 0 )
- /* ignore it and it will go away */;
- else if ( strcmp(field, "../") == 0 || strcmp(field,"..")==0){
-
- /* back up a field - if attempt to back up too far
- ignore the request */
- if (end != path + strlen(root) +1) {
- end--;
- while (*--end != SLASHCH) ;
- *++end = EOSCH;
- /* first character is a slash so
- can't run off the start (happen!) */
- }
- }
-
- else /* append the string to the path string */
- {
- /* MAXPATH characters includes the EOS */
- if (end-path+flen >= MAXPATH) return(ERR);
- strcat(path,"/");
- strcat(path, field);
- end += flen;
- }
-
- } while (exit != EOS);
-
- return(OK);
- }
-
- mkfilnm(istname, filenam, status)
- int *istname;
- char *filenam;
- struct filinfo * status;
- {
-
- /* transform the IST string into a UNIX file name
-
- 1. If first character is HOSTFILE_ID then strip it off and
- pass it back.
-
- 2. Else it is a PFS file. Build a path of the form
- pfs root directory/ local directory path/ istname
-
- where prs root directory is stored in root, local directory path
- is stored in localdir (both extern).
-
- For details of the form of ISTNAME see the comments in mkpath.
-
- This is a 'middle of the road implementation'.
-
- On a UNIX system it should be possible to just glue the path
- components together and let UNIX sort it out. Decoding is done
- here in an attempt to minimize the string length of the final
- path name */
-
- /* on exit status contains three integer fields
-
- ftype subtype exists
- HOST UNDEFINED YES/NO
- VFS PLAIN/DIRECTORY YES/NO
- DEVICE STDIN,STDOUT,STDERR,STDLST UNDEFINED
- ERR UNDEFINED UNDEFINED
- */
-
- char path[MAXPATH], *ptr, *ptr2, *start;
-
- istchr_(istname, path);
-
- /* check for host file */
- ptr = path;
- if (*ptr == HOSTFILE_IDCH) {
- start = ++ptr;
- *filenam++ = *ptr;
-
- /* null name - error */
- if(*ptr == EOSCH){
- status->ftype1 = ERR;
- status->subtype = status->exists = UNDEFINED;
- return;
- }
-
- /* check for preconnected units */
- stdunit(ptr, status);
- if(status->ftype1 == DEVICE) {
- *filenam = EOSCH;
- return;
- }
-
- /* otherwise its a host file name proper */
- status->ftype1 = HOST;
- status->subtype = UNDEFINED;
- while (*ptr != EOSCH) *filenam++ = *++ptr;
- *filenam = EOSCH;
-
- /* check for existence */
- status->exists = isafile(start);
- /* or a directory - error in host file case */
- if (isadir(start) == YES) {
- status->ftype1 = ERR;
- status->subtype = status->exists = UNDEFINED;
- return;
- }
- return;
-
- }
-
-
- /* deal with pfs name */
- /* convert to lower case and strip off leading white space */
-
- for(ptr = path; *ptr == BLANKCH || *ptr == TABCH; ptr++) ;
- ptr2 = ptr;
- while ( *ptr2 != EOSCH ) {
- *ptr2 = ( isupper(*ptr2) ? tolower(*ptr2) : *ptr2);
- ptr2++;
- }
-
- /* check for null name */
- if (*ptr == EOSCH) {
- status->ftype1 = ERR;
- status->subtype = status->exists = UNDEFINED;
- return;
- }
-
- /* check for preconnected unit */
- stdunit(ptr, status);
- if (status->ftype1 == DEVICE) return;
-
- /* make up a path name */
- if(mkpath(ptr ,filenam) == ERR) {
- status->ftype1 = ERR;
- status->subtype = status->exists = UNDEFINED;
- return;
- }
-
- /* otherwise return vfs info */
- status->ftype1 = VFS;
-
- /* test to see if it exists */
- status->exists = isafile(filenam);
-
- /* and if it is a directory */
- status->subtype = ((isadir(filenam) == YES) ? DIRECTORY : PLAIN);
-
- return;
- }
-
-
- opnread(fd)
- int fd;
-
- {
- /* ensure that the file connected through the file
- descriptor fd is
-
- (i) open (ERR if not)
-
- (ii) has access = read or readwrite (ERR if not)
-
- (iii) has currentaccess set to read if open in readwrite
- this may require a write and a rewind. */
-
-
- struct fdinfo *ptr;
-
- /* check for valid file descriptor */
- if ( checkfd(fd) == NOTINRANGE ) {
- remark_("invalid file descriptor in putch", 32L);
- return (ERR) ;
- }
-
- ptr = &files[fd];
-
- /* error conditions first */
- if ( ptr->access == NOTOPEN || ptr->access == WRITE){
- remark_("file not open or open for reading only", 38L);
- return(ERR);
- }
-
- /* must be read or readwrite - check currentaccess */
- if(ptr->caccess == WRITE) {
- write(fd, ptr->buffer, ptr->chrleft);
- lseek(fd,0L,0);
- ptr->caccess = READ;
- ptr->chrleft = 0;
- }
- return(OK);
- }
-
- opnwrit(fd)
- int fd;
-
- {
- /* ensure that the file connected through the file
- descriptor fd is
-
- (i) open (ERR if not)
-
- (ii) has access = write or readwrite (ERR if not)
-
- (iii) has currentaccess set to write if open in readwrite
- this may require a rewind. */
-
-
- struct fdinfo *ptr;
- int istname[MAXPATH], pmode=0644;
-
- /* check for valid file descriptor */
- if ( checkfd(fd) == NOTINRANGE ) {
- remark_("invalid file descriptor in putch", 32L);
- return (ERR) ;
- }
-
- ptr = &files[fd];
-
- /* error conditions first */
- if ( ptr->access == NOTOPEN || ptr->access == READ){
- remark_("file not open or open for reading only", 38L);
- return(ERR);
- }
-
- /* if access = WRITE then return OK */
- if (ptr->access == WRITE) return(OK);
-
- /* access is now READWRITE - if currentaccess is READ
- then truncate the file to zero length and reopen
- it with the same fd.
-
- Careful with filenames here because any leading
- HOSTFILE_IDCH have been eaten ! */
-
-
- if(ptr->caccess == READ) {
- fd = crtzlng(ptr->filenam, READWRITE, fd);
- ptr->caccess = WRITE;
- ptr->chrleft = 0;
- }
- return(OK);
- }
-
-
-
- prconfl(unit, access)
- int access, unit;
- {
- /* If access = READ, WRITE, READWRITE and the file is
- a preconnected unit then a check is made that the
- access mode is legal.,
- i.e. not READ for STDERR, STDOUT, STDLST
- and not WRITE for STDIN. */
-
- switch ( unit )
- {
- case STDIN :
- return (access == WRITE ? ERR : NOERR);
-
- default:
- return (access == READ ? ERR : NOERR);
-
- }
- }
-
- stdunit(ptr, status)
- char *ptr;
- struct filinfo * status;
- {
-
- /* returns a fileinfo pointer if ptr is pointing at a preconnnected
- file else returns (ERR,UNDEFINED,UNDEFINED) */
-
-
- /* set up default values */
- status->ftype1 = ERR;
- status->subtype = status->exists = UNDEFINED;
-
- if (strcmp(ptr,"0") == 0 || strcmp(ptr,"1") == 0
- || strcmp(ptr,"2") == 0 || strcmp(ptr,"3") == 0 ){
- status->ftype1 = DEVICE;
- status->subtype = *ptr - '0';
- }
-
- return;
-
- }
-
-
- #ifdef VER4.1
-
- tmkdir(charnm1, mode)
- int mode;
- char *charnm1;
- {
-
- /* create a new directory with name name in the local directory
- The name name must be unique in this directory */
-
- int pid, status, w;
-
- if((pid = fork()) == -1) return(ERR);
-
- /* mode unused but passed through for consistency with
- 4.2 in the hope it may be useful one day ! */
- if(pid == 0) execl(MKDIRPTH, "mkdir", charnm1, (char *) 0);
-
- while((w = wait(&status)) != pid && w != -1) ;
-
- if(w == -1) return(ERR);
-
- return(NOERR);
-
- }
-
- trmdir(charnm1)
- char *charnm1;
- {
-
- /* delete an empty directory with name name in the local directory
- The name name must be unique in this directory */
-
- int pid, status, w;
-
- if((pid = fork()) == -1) return(ERR);
-
- if(pid == 0) execl(RMDIRPTH, "rmdir", charnm1, (char *) 0);
-
- while((w = wait(&status)) != pid && w != -1) ;
-
- if(w == -1) return(ERR);
-
- return(NOERR);
-
- }
-
- #endif
-
- outcmps(status)
- int *status;
- {
-
- /* output the completion status if an error has occurred */
-
- int fderr = STDERR;
-
- zchout_("Tool Termination Status: .", &fderr, 26L);
-
- switch (*status) {
-
- case WARNING:
- zmess_("WARNING.", &fderr, 8L);
- break;
-
- case ERROR:
- zmess_("ERROR.", &fderr, 6L);
- break;
-
- case FATAL:
- zmess_("FATAL.", &fderr, 6L);
- break;
-
- case KILL:
- zmess_("KILL.", &fderr,5L);
- break;
-
- case TERMFLAG_0:
- zmess_("TERMFLAG_0.", &fderr,11L);
- break;
-
- case TERMFLAG_1:
- zmess_("TERMFLAG_1.", &fderr,11L);
- break;
-
- case TERMFLAG_2:
- zmess_("TERMFLAG_2.", &fderr,11L);
- break;
-
-
- }
- }
-
- writipc(status)
- int *status;
- {
-
- /* write the inter process communication file */
-
- char lcltmp[MAXPATH];
- int istname[MAXPATH], fd, access = WRITE, length, size = MAXPATH;
- int i, newline = NEWLINE;
-
- /* keep current directory and change to root */
- strcpy(lcltmp, lcldir);
- chist_("/", istname, 1L);
- zlocal_(istname);
-
- /* create an empty inter process communication file */
- chist_(IPCFILE, istname, strlen(IPCFILE));
- fd = create_(istname, &access);
-
- /* output status information */
- length = itoc_(status, istname, &size);
- zptmes_(istname, &fd);
- /* output lcldir, root and nxttool */
- chist_(lcltmp, istname, strlen(lcltmp));
- zptmes_(istname, &fd);
- chist_(root, istname, strlen(root));
- zptmes_(istname, &fd);
- chist_(nxttool, istname, strlen(nxttool));
- zptmes_(istname, &fd);
-
- /* output the information stored in the outparam
- array - a null value means that no argument has been
- assigned */
- for (i=3; i <= MAXPRAM+2; i++) {
- if (outparm[i] == NULLST) /* output a blank line */
- putch_(&newline, &fd);
- else {
- chist_(outparm[i], istname, strlen(outparm[i]));
- zptmes_(istname, &fd);
- }
- }
-
- /* close the inter process communication file */
- close_(&fd);
- }
-
- xexit()
- {
-
- /* general tidying up routine */
-
- char charnm[MAXPATH];
- int istname[MAXPATH], i;
- struct filinfo finf;
-
- /* close all sequential and direct access files - flushing
- output as necessary */
- ztidy_();
-
- /* close current directory descriptor */
- if(dirp != (DIR*) NULLST) closedir(dirp);
- if(DEBUG) {
- for (i=FIRSTFD;i<MAXFILE;i++)
- if(close(i) == 0) printf("unclosed fd %d closed",i);
- }
-
- /* flush the device files */
- flush(STDOUT);
- flush(STDERR);
- flush(STDLST);
-
- /* print spool file and delete it - this assumes the system
- copies the list file and doesn't just remember the name */
- zspool_();
- close(STDLST);
- chist_(SPFLNAME, istname, strlen(SPFLNAME));
- mkfilnm(istname, charnm, &finf);
- unlink(charnm);
-
- }
-
- #ifdef SHELL_SCRIPTS
- outinfo(status)
- int *status;
- {
-
- /* create the file INFOFILE and write status therein */
-
- #define INFOFILE "_.info"
-
- int infofile[MAXPATH];
- int wmode = WRITE;
- int width = 1;
- int fdifile;
-
- chist_(INFOFILE, infofile, strlen(INFOFILE));
- fdifile = create_(infofile,&wmode);
- zptint_(status,&width,&fdifile);
- }
- #endif
-